package ch.bfh.fbi.mobicomp.zap03;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import ch.quantasy.android.speech.SpeechService;
import ch.quantasy.android.speech.string.FrenchString;
import ch.quantasy.android.speech.string.GermanString;
import ch.quantasy.android.speech.string.UKString;

/**
 * In Zap02 we have seen how to do somewhat more complex stuff. So let us get a
 * little bit more serious about it. What if we want to create an application
 * that runs longer than just two seconds?
 * 
 * @author quantasy
 * 
 */
public class Zap03MessageBroadcastReceiver extends BroadcastReceiver {
	public static final String REMOTE_ZAPPER_ACTION = "ch.bfh.fbi.mobicomp.zap03.Zap03MessageBroadcastReceiver.REMOTE_ZAPPER_ACTION";
	public static final String ZAPPER_KEY_WORD = "ZAP:";
	private static final String destructionKey = "destroyMe";
	private static final String haltKey = "stopDestroyMe";

	private final Intent speechIntent;
	private long countdown;
	private Context context;

	private static final String TAG = "ZAP03";

	public static Intent getRemoteZapperMessageIntent(final String message) {
		Intent intent = null;
		if (message.startsWith(Zap03MessageBroadcastReceiver.ZAPPER_KEY_WORD)) {
			intent = new Intent(
					Zap03MessageBroadcastReceiver.REMOTE_ZAPPER_ACTION);
			intent.putExtra("message", message
					.substring(Zap03MessageBroadcastReceiver.ZAPPER_KEY_WORD
							.length()));
		}
		return intent;
	}

	public Zap03MessageBroadcastReceiver() {
		this.speechIntent = SpeechService.getSpeechIntent();
	}

	@Override
	public void onReceive(final Context context, final Intent intent) {
		Log.d(Zap03MessageBroadcastReceiver.TAG, "Service Intent received: "
				+ intent);
		if (intent == null) {
			return;
		}
		this.context = context;
		if (Zap03MessageBroadcastReceiver.destructionKey.equals(intent
				.getExtras().getString("message"))) {
			Log.d(Zap03MessageBroadcastReceiver.TAG, "destruction initiated...");
			this.initiateAutoDestruction();
			Log.d("Zapper", "Start");
		} else if (Zap03MessageBroadcastReceiver.haltKey.equals(intent
				.getExtras().getString("message"))) {
			Log.d(Zap03MessageBroadcastReceiver.TAG, "destruction aborted...");
			this.resetAutoDestruction();
			Log.d(Zap03MessageBroadcastReceiver.TAG, "stop");
		}

		else {
			Log.d(Zap03MessageBroadcastReceiver.TAG, "unknown command.");
		}
	}

	private void resetAutoDestruction() {
		if (this.countdown == 0) {
			return;
		}
		Thread.currentThread().interrupt();
		this.countdown = 0;

		SpeechService.setPhrase(this.speechIntent, new UKString(
				"Self destruction sequence aborted."), new GermanString(
				"Selbstzerstörungssequenz abgebrochen."), new FrenchString(
				"Séquence d'autodestruction avortée."));
		this.context.startService(this.speechIntent);
	}

	private void initiateAutoDestruction() {
		if (this.countdown != 0) {
			return;
		}
		this.countdown = System.currentTimeMillis() + (3 * 60 * 1000);
		SpeechService.setPhrase(this.speechIntent, new UKString(
				"Self destruction sequence initiated."), new GermanString(
				"Selbstzerstörungs Sequenz eingeleitet."), new FrenchString(
				"Séquence d'autodestruction declanchée."));
		this.context.startService(this.speechIntent);
		this.countDown();
	}

	private void countDown() {
		try {
			int timeLeft = (int) ((this.countdown - System.currentTimeMillis()) / 1000);
			while (timeLeft > 70) {
				this.minutesCount(timeLeft);
				Thread.sleep(60000); // 1 Minute
				timeLeft = (int) ((this.countdown - System.currentTimeMillis()) / 1000);
			}
			while (timeLeft > 11) {
				this.secondsBlockCount(timeLeft);
				Thread.sleep(10000); // 10 Seconds
				timeLeft = (int) ((this.countdown - System.currentTimeMillis()) / 1000);
			}
			while (timeLeft > 0) {
				this.secondsCount(timeLeft);
				Thread.sleep(1000); // 1 Second
				timeLeft = (int) ((this.countdown - System.currentTimeMillis()) / 1000);
			}
			this.destroy();
		} catch (final InterruptedException ex) {
		}
	}

	private void minutesCount(final int timeLeft) {
		SpeechService.setPhrase(this.speechIntent, new UKString(""
				+ (1 + (timeLeft / (60))) + "Minutes until self destruction"),
				new GermanString("" + (1 + (timeLeft / (60)))
						+ "Minuten bis zur Selbstzerstörung"),
				new FrenchString("" + (1 + (timeLeft / (60)))
						+ "minutes jusqu'à ce que l'auto-destruction"));
		this.context.startService(this.speechIntent);
	}

	private void secondsBlockCount(final int timeLeft) {
		if ((timeLeft % 3) == 0) {
			SpeechService.setPhrase(this.speechIntent, new UKString(""
					+ (10 + ((timeLeft / 10) * 10))
					+ "Seconds until self destruction"));
		} else if ((timeLeft % 3) == 1) {
			SpeechService.setPhrase(this.speechIntent, new GermanString(""
					+ (10 + ((timeLeft / 10) * 10))
					+ "Sekunden bis zur Selbstzerstörung"));
		} else {
			SpeechService.setPhrase(this.speechIntent, new FrenchString(""
					+ (10 + ((timeLeft / 10) * 10))
					+ "seconds jusqu'à ce que l'auto-destruction"));
		}
		this.context.startService(this.speechIntent);
	}

	private void secondsCount(final int timeLeft) {
		SpeechService.setPhrase(this.speechIntent,
				new UKString("" + (timeLeft)));
		this.context.startService(this.speechIntent);
	}

	private void destroy() {
		this.countdown = 0;
		SpeechService.setPhrase(this.speechIntent, new UKString(
				"Self destroying now."));
		this.context.startService(this.speechIntent);
	}

}
